package com.rljk.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.rljk.common.consts.AssetConst;
import com.rljk.common.dao.DaoSupport;
import com.rljk.config.property.TencentProperty;
import com.rljk.domain.common.PageData;
import com.rljk.domain.po.TrustSqlDigitalAssets;
import com.rljk.domain.po.TrustSqlIdentify;
import com.rljk.service.AssetsManager;
import com.rljk.service.TrustSqlManager;
import com.rljk.utils.*;
import com.tencent.trustsql.sdk.Constants;
import com.tencent.trustsql.sdk.TrustSDK;
import com.tencent.trustsql.sdk.bean.PairKey;
import com.tencent.trustsql.sdk.util.HttpClientUtil;
import com.tencent.trustsql.sdk.util.SignStrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/** 
 * 说明： 腾讯区块链接口
 * 创建人：zhaozhenhua
 * 创建时间：2018-07-26
 * @version
 */
@Service("trustSqlService")
@Slf4j
public class TrustSqlService implements TrustSqlManager {

	@Resource(name = "assetsService")
	private AssetsService assetsService;


	/**
	 *TrustSql身份管理-注册用户
     * USER_ID  用户ID
     * USERNAME  用户名
	 */
	@Override
	public Object userCertRegister(PageData pd) throws Exception {

	    log.info("TrustSql身份管理-注册用户");
        PairKey pairKey = TrustSDK.generatePairKey();

        JSONObject json = new JSONObject();
        json.put("user_id",pd.get("USER_ID"));//用户ID
        json.put("public_key",pairKey.getPublicKey());//用户公钥
        json.put("user_fullName",pd.get("USERNAME"));//用户名

        TrustSqlIdentify identify = new TrustSqlIdentify(json);
        SortedMap<String, Object> map = identify.getMap();
        map.put("sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(map).getBytes(), false));

        JSONObject postJson = new JSONObject();
        for (String key : map.keySet()) {
            postJson.put(key, map.get(key));
        }

        log.info("请求参数postJson："+postJson.toJSONString());

        String url = AssetConst.user_cert_register;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson.toJSONString());

        if ("0".equals(resultJson.getString("retcode")) && "Success".equals(resultJson.getString("retmsg"))) {
            log.info("TrustSql注册用户成功");
            pd.put("PUBLIC_KEY",pairKey.getPublicKey());
            pd.put("PRIVATE_KEY",pairKey.getPrivateKey());
            pd.put("ASSETS_ID", SnowIdUtil.getSnowId());
            assetsService.save(pd);
        }
        return resultJson;
	}

    /**
     * TrustSql身份管理-获取用户信息
     * USER_ID    用户ID
     */
	@Override
    public Object userCertFetch(PageData pd) throws Exception {

        log.info("TrustSql身份管理-获取用户信息");

        JSONObject json = new JSONObject();
        json.put("user_id",pd.get("USER_ID"));//用户ID


        TrustSqlIdentify identify = new TrustSqlIdentify(json);
        SortedMap<String, Object> map = identify.getMap();
        map.put("sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(map).getBytes(), false));

        JSONObject postJson = new JSONObject();
        for (String key : map.keySet()) {
            postJson.put(key, map.get(key));
        }

        log.info("请求参数postJson："+postJson.toJSONString());

        String url = AssetConst.user_cert_fetch;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson.toJSONString());

        if ("0".equals(resultJson.getString("retcode")) && "Success".equals(resultJson.getString("retmsg"))) {
            return resultJson.toJSONString();
        }
        return null;
    }


    /**
     * TrustSql身份管理-创建用户账户
     *  USER_ID  用户ID
     *  PUBLIC_KEY  用户公钥
     */
    @Override
    @Transactional
    public Object accountCertRegister(PageData pd) throws Exception {

        log.info("TrustSql身份管理-创建用户账户");

        JSONObject json = new JSONObject();
        json.put("user_id",pd.get("USER_ID"));//用户ID
        json.put("public_key",pd.get("PUBLIC_KEY"));//用户公钥


        TrustSqlIdentify identify = new TrustSqlIdentify(json);
        SortedMap<String, Object> map = identify.getMap();
        map.put("sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(map).getBytes(), false));

        JSONObject postJson = new JSONObject();
        for (String key : map.keySet()) {
            postJson.put(key, map.get(key));
        }

        log.info("请求参数postJson："+postJson.toJSONString());

        String url = AssetConst.account_cert_register;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson.toJSONString());

        if ("0".equals(resultJson.getString("retcode"))) {
            String retdata=resultJson.getString("retdata");
            JSONObject retData = JSONObject.parseObject(retdata);
            log.info("retData:"+retData);
            log.info("retData:"+retData.toJSONString());
            String account_address=retData.getString("account_address");
            log.info("account_address:"+account_address);
            pd.put("ACCOUNT_ADDRESS",account_address);
            assetsService.edit(pd);

            return resultJson.toJSONString();
        }
        return null;
    }


    /**
     * TrustSql身份管理-获取用户的账户地址列表
     * USER_ID   用户ID
     */
    @Override
    public String accountCertFetchList(String USER_ID) throws Exception {
        log.info("TrustSql身份管理-获取用户的账户地址列表");

        JSONObject json = new JSONObject();
        json.put("user_id",USER_ID);//用户ID


        TrustSqlIdentify identify = new TrustSqlIdentify(json);
        SortedMap<String, Object> map = identify.getMap();
        map.put("sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(map).getBytes(), false));

        JSONObject postJson = new JSONObject();
        for (String key : map.keySet()) {
            postJson.put(key, map.get(key));
        }

        log.info("请求参数postJson："+postJson.toJSONString());

        String url = AssetConst.account_cert_fetch_list;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson.toJSONString());

        if ("0".equals(resultJson.getString("retcode")) && "Success".equals(resultJson.getString("retmsg"))) {
            return resultJson.toJSONString();
        }
        return null;
    }

    /**
     * TrustSql数字资产-资产发行申请
     * amount  资产份额
     */
    @Override
    public String assetIssueApply(PageData pd) throws Exception {
        log.info("TrustSql数字资产-资产发行申请");

        TrustSqlDigitalAssets digitalAssets = new TrustSqlDigitalAssets();
        TreeMap<String, Object> paramMap = digitalAssets.getMap();

        paramMap.put("owner_account", AssetConst.owner_account);
        paramMap.put("asset_type", AssetConst.asset_type);
        paramMap.put("amount", pd.getInterger1("amount"));//资产份额
        paramMap.put("unit", AssetConst.unit);

        Map<String,Object> map = new HashMap<>();
        map.put("info","发布资产");
        Object o = JSONObject.toJSON(map);
        log.info("content:"+o.toString());

        paramMap.put("content", o);
        paramMap.put("mch_sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(paramMap).getBytes(), false));
        // generate post data
        JSONObject postJson = new JSONObject();
        for (String key : paramMap.keySet()) {
            postJson.put(key, paramMap.get(key));
        }

        log.info("请求参数postJson:"+postJson.toJSONString());

        String url = AssetConst.asset_issue_apply;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson);

        //验签
        String resultJson1 = TrustSqlUtil.verifyString(paramMap, resultJson);
        return resultJson1;
    }

    /**
     * TrustSql数字资产-资产发行提交
     */
    @Override
    public String assetIssueSubmit(String applyResult) throws Exception {
        log.info("TrustSql数字资产-资产发行提交");
        JSONObject applyResultJson = JSONObject.parseObject(applyResult);

        TrustSqlDigitalAssets digitalAssets = new TrustSqlDigitalAssets();
        TreeMap<String, Object> paramMap = digitalAssets.getMap();

        paramMap.put("transaction_id", applyResultJson.get("transaction_id"));//交易ID
        paramMap.put("asset_type", AssetConst.asset_type);//资产类型
        paramMap.put("asset_id", applyResultJson.get("asset_id"));//资产ID

        JSONArray sign_str_list = applyResultJson.getJSONArray("sign_str_list");
        JSONArray sign_list = TrustSqlUtil.getSignList(sign_str_list);

        paramMap.put("sign_list", sign_list);
        //paramMap.put("mch_sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(paramMap).getBytes(), false));
        log.info("带签名原串:"+SignStrUtil.mapToKeyValueStr(paramMap));
        log.info("带签名原串SignUtil:"+ SignUtil.getUrlParamsByMap(paramMap));
        paramMap.put("mch_sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(paramMap).getBytes(), false));
        // generate post data
        JSONObject postJson = new JSONObject();
        for (String key : paramMap.keySet()) {
            postJson.put(key, paramMap.get(key));
        }
        log.info("请求参数postJson:"+postJson.toJSONString());

        String url = AssetConst.asset_issue_submit;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson);

        //验签
        String resultJson1 = TrustSqlUtil.verifyString(paramMap, resultJson);
        return resultJson1;
    }

    /**
     * TrustSql数字资产-资产转让至中间账户申请(转让签收场景)
     * src_user_id
     * dst_user_id
     * src_asset_id
     * amount
     */
    @Override
    public String assetTransferMidApply(PageData pd) throws Exception {
        log.info("TrustSql数字资产-资产转让至中间账户申请(转让签收场景)");

        String src_user = accountCertFetchList(pd.getString("src_user_id"));
        String dst_user = accountCertFetchList(pd.getString("dst_user_id"));
        String src_account = TrustSqlUtil.getAccount(src_user);
        String dst_account = TrustSqlUtil.getAccount(dst_user);


        TrustSqlDigitalAssets digitalAssets = new TrustSqlDigitalAssets();
        TreeMap<String, Object> paramMap = digitalAssets.getMap();

        paramMap.put("src_account", src_account);//资产转出帐户
        paramMap.put("dst_account", dst_account);//资产转入帐户
        paramMap.put("src_asset_id", pd.getString("src_asset_id"));//转出账户持有的资产ID
        paramMap.put("asset_type", AssetConst.asset_type);//资产类型
        paramMap.put("amount", pd.getString("amount"));//转让份额
        paramMap.put("mch_sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(paramMap).getBytes(), false));

        JSONObject postJson = new JSONObject();
        for (String key : paramMap.keySet()) {
            postJson.put(key, paramMap.get(key));
        }
        log.info("请求参数postJson:"+postJson.toJSONString());

        String url = AssetConst.asset_transfer_mid_apply;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson);

        //验签
        String verifyString = TrustSqlUtil.verifyString(paramMap, resultJson);
        return verifyString;
    }

    /**
     * TrustSql数字资产-资产转让至中间账户提交(转让签收场景)
     */
    @Override
    public String assetTransferMidSubmit(String assetTransferMidApplyReslut) throws Exception {
        log.info("TrustSql数字资产-资产转让至中间账户提交(转让签收场景)");

        JSONObject json = JSONObject.parseObject(assetTransferMidApplyReslut);

        TrustSqlDigitalAssets digitalAssets = new TrustSqlDigitalAssets();
        TreeMap<String, Object> paramMap = digitalAssets.getMap();

        JSONArray sign_str_list = json.getJSONArray("sign_str_list");
        Object sign_list = TrustSqlUtil.getSignList(sign_str_list);

        paramMap.put("transaction_id", json.getString("transaction_id"));//交易ID
        paramMap.put("asset_type", AssetConst.asset_type);//资产类型
        paramMap.put("sign_list", sign_list);//签名列表
        paramMap.put("mch_sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(paramMap).getBytes(), false));

        JSONObject postJson = new JSONObject();
        for (String key : paramMap.keySet()) {
            postJson.put(key, paramMap.get(key));
        }
        log.info("请求参数postJson:"+postJson.toJSONString());

        String url = AssetConst.asset_transfer_mid_submit;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson);

        //验签
        String verifyString = TrustSqlUtil.verifyString(paramMap, resultJson);
        return verifyString;
    }

    /**
     * TrustSql数字资产-资产转让签收申请(转让签收场景)
     * pd
     * assetTransferMidSubmitResult
     * op_code
     */
    @Override
    public String assetSigninApply(PageData pd,String assetTransferMidSubmitResult,int op_code) throws Exception {
        log.info("TrustSql数字资产-资产转让签收申请(转让签收场景)");

        JSONObject json = JSONObject.parseObject(assetTransferMidSubmitResult);

        String src_user = accountCertFetchList(pd.getString("src_user_id"));
        String dst_user = accountCertFetchList(pd.getString("dst_user_id"));
        String src_account = TrustSqlUtil.getAccount(src_user);
        String dst_account = TrustSqlUtil.getAccount(dst_user);


        TrustSqlDigitalAssets digitalAssets = new TrustSqlDigitalAssets();
        TreeMap<String, Object> paramMap = digitalAssets.getMap();

        paramMap.put("src_account", src_account);//资产转出帐户
        paramMap.put("dst_account", dst_account);//资产转入帐户
        paramMap.put("mid_asset_id", json.getString("mid_asset_id"));//中间账户资产ID
        paramMap.put("asset_type", AssetConst.asset_type);//资产类型
        paramMap.put("amount", json.getString("mid_asset_amount"));//转至中间账户的资产份额
        paramMap.put("op_code", op_code);//操作类型1 签收;2 拒绝;3 撤销  int
        paramMap.put("mch_sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(paramMap).getBytes(), false));

        JSONObject postJson = new JSONObject();
        for (String key : paramMap.keySet()) {
            postJson.put(key, paramMap.get(key));
        }
        log.info("请求参数postJson:"+postJson.toJSONString());

        String url = AssetConst.asset_signin_apply;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson);

        //验签
        String verifyString = TrustSqlUtil.verifyString(paramMap, resultJson);
        return verifyString;
    }

    /**
     * TrustSql数字资产-资产转让签收提交(转让签收场景)
     */
    @Override
    public String assetSigninSubmit(String assetSigninApplyResult) throws Exception {
        log.info("TrustSql数字资产-资产转让签收提交(转让签收场景))");

        JSONObject json = JSONObject.parseObject(assetSigninApplyResult);

        TrustSqlDigitalAssets digitalAssets = new TrustSqlDigitalAssets();
        TreeMap<String, Object> paramMap = digitalAssets.getMap();

        JSONArray sign_str_list = json.getJSONArray("sign_str_list");
        Object sign_list = TrustSqlUtil.getSignList(sign_str_list);

        paramMap.put("transaction_id", json.getString("transaction_id"));//交易ID
        paramMap.put("asset_type", AssetConst.asset_type);//资产类型
        paramMap.put("sign_list", sign_list);//签名列表
        paramMap.put("mch_sign", TrustSDK.signString(AssetConst.COMMUNICATION_PRIVATE_KEY, SignStrUtil.mapToKeyValueStr(paramMap).getBytes(), false));

        JSONObject postJson = new JSONObject();
        for (String key : paramMap.keySet()) {
            postJson.put(key, paramMap.get(key));
        }
        log.info("请求参数postJson:"+postJson.toJSONString());

        String url = AssetConst.asset_signin_submit;
        String result = HttpClientUtil.post(url, postJson.toJSONString());
        // 分析http请求结果
        JSONObject resultJson = JSONObject.parseObject(result);
        log.info("分析http请求结果resultJson:"+resultJson);

        //验签
        String verifyString = TrustSqlUtil.verifyString(paramMap, resultJson);
        return verifyString;
    }


}

